package com.fuyun.microservice.proxy;


import com.alibaba.fastjson.JSON;
import com.fuyun.microservice.GlobalConstant;
import com.fuyun.microservice.ResultObject;
import com.fuyun.microservice.codec.msg.QueryRequestMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.StreamUtils;

import java.io.IOException;

import static com.fuyun.microservice.utils.BufferUtil.CHARSET_DEFAULT;

@Component
@Slf4j
public class ForwardFactory {
    private final RestForward restForward;
    private final DiscoveryRoute discoveryRoute;

    public ForwardFactory(RestForward restForward, DiscoveryRoute discoveryRoute) {
        this.restForward = restForward;
        this.discoveryRoute = discoveryRoute;
    }

    public ForwardResult forward(QueryRequestMessage queryRequestMessage) {
        log.debug("req body：{}", queryRequestMessage.toString());
        DiscoveryRoute.ForwardRoute route = discoveryRoute.match(queryRequestMessage.getUri());
        if (route == null) {
            return ForwardResult.buildFailed(-1, "uri not valid");
        }

        ForwardContext forwardContext = new ForwardContext();
        forwardContext.setUri(route.getServiceUri());
        forwardContext.setRemoteIp("127.0.0.1");
        int bodyLength = queryRequestMessage.getRequestBytes().length;
        forwardContext.setBodyBytes(queryRequestMessage.getRequestBytes());
        forwardContext.setBodyLength(bodyLength);
        try {
            ClientHttpResponse clientHttpResponse = restForward.forward(route.getServiceId(), forwardContext);
            if (clientHttpResponse.getStatusCode() != HttpStatus.OK) {
                return ForwardResult.buildFailed(clientHttpResponse.getStatusCode().value(), "proxy failed");
            }

            String rspBody = StreamUtils.copyToString(clientHttpResponse.getBody(), CHARSET_DEFAULT);
            log.debug("rsp body:{}", rspBody);
            return JSON.parseObject(rspBody, ForwardResult.class);
        } catch (Exception ex) {
            log.error("forward error", ex);
            return ForwardResult.buildFailed(500, "forward error");
        }
    }
}
